package com.china.produce.executor;

import com.china.produce.annotation.RequiresRoles;
import com.china.produce.executor.impl.DemoMethodJobHandler;
import com.xxl.job.core.handler.IJobHandler;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.MethodIntrospector;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * @ClassName
 * @Author niujie
 * @Version
 * @Description
 * @CreateTime 2023/6/24
 */
@Component
public class DemoXxlJobSpringExecutor implements ApplicationContextAware, SmartInitializingSingleton {

    private static ApplicationContext applicationContext;

    private static ConcurrentMap<String, JobHandler> jobHandlerRepository = new ConcurrentHashMap<String, JobHandler>();

    @Override
    public void afterSingletonsInstantiated() {
        String[] beanDefinitionNames = applicationContext.getBeanNamesForType(Object.class, false, true);

        for (String beanDefinitionName : beanDefinitionNames) {
            Map<Method, RequiresRoles> methodRequiresRolesMap = null;
            Object bean = applicationContext.getBean(beanDefinitionName);
            try{
                methodRequiresRolesMap = MethodIntrospector.selectMethods(bean.getClass(), new MethodIntrospector.MetadataLookup<RequiresRoles>() {
                    @Override
                    public RequiresRoles inspect(Method method) {

                        return AnnotatedElementUtils.findMergedAnnotation(method, RequiresRoles.class);
                    }
                });
            }catch (Exception e) {
            }
            if (methodRequiresRolesMap == null || methodRequiresRolesMap.isEmpty()) {
                continue;
            }
            for (Map.Entry<Method, RequiresRoles> methodRequiresRoles : methodRequiresRolesMap.entrySet()) {
                RequiresRoles requiresRoles = methodRequiresRoles.getValue();
                String[] name = requiresRoles.value();
                if (name.length == 0) {
                    System.out.println("++++++++++");
                }
                Method method = methodRequiresRoles.getKey();
                method.setAccessible(true);
                registerJobHandler(name[0], new DemoMethodJobHandler(bean, method));
            }
        }
    }

    public void registerJobHandler(String name, JobHandler jobHandler) {

        jobHandlerRepository.put(name, jobHandler);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

        DemoXxlJobSpringExecutor.applicationContext = applicationContext;
    }
}
